#include "stdafx.h"

#include "../../../include/common/base.h"
#include "../../../include/rtdbms/rtdb_sys.h"

#include "../../../include/common/filehelper.h" 

using namespace std; 

#include "../../../include/rtdbms/rtdbFun.h"

//#include<afx.h>

extern struUsrPointer  LibDetails[MaxLibNo + 1];
extern struShareMen*  SysPtr ; 

extern bool CheckCanBeUsedByLibNo( int lib_no ); 
extern bool IsRecordUsed( struLibrary* pLib, char* pRec );
extern char* KeyToAddress(int TheLibNo, unsigned int TheKey);
extern int hashGetNextRecKey(struLibrary* pLib, char* pRec);
extern void hashSetNextRecKey(struLibrary* pLib, char* pRec, int lNextRecKey);
 
const int RTDB_STRING_KEY_NO = 2;
const int REC_FILED_NAME_LEN = 64;  //�� struct SYS_STRING_KEY ��һ��

 


int StringkeyToRecAddr(char * string_key)
{   
	if( string_key==NULL || strlen(string_key)<= 0  ) return -1; 

	int Key_id = HashGetRecKey(RTDB_STRING_KEY_NO, string_key, strlen(string_key));  //

	if( !IsLibNoValid(RTDB_STRING_KEY_NO) )   {
		//printf("IsLibNoValid(RTDB_STRING_KEY_NO) \n");
		return -1; 
	}
	struLibrary * pTempLib = &(SysPtr->TheLibMsgArray[RTDB_STRING_KEY_NO]);  
	if( pTempLib->IsUsed == NOTUSED ) {
		//printf("pTempLib->IsUsed == NOTUSED\n");
		return -1;  
	}
	int nAdr = Key_id %  pTempLib->BaseCount;  

	char* pTempRec;
	do
    	{
		pTempRec = KeyToAddress(RTDB_STRING_KEY_NO, nAdr);       
		if(pTempRec == 0) {
			//printf("KeyToAddress == 0\n");
			return -1; 
		}

		if( IsRecordUsed( pTempLib, pTempRec ) == true ) {  
			char   rec_name[64] = {0}; 
			memcpy(rec_name, pTempRec, REC_FILED_NAME_LEN); 
			if( strcmp(rec_name, string_key) == 0)  
			{    
				//unsigned short rec_addr_key;
				//memcpy(&rec_addr_key, &pTempRec[REC_FILED_NAME_LEN], sizeof(short) ); 
				return nAdr;
			}
		}  

		nAdr = hashGetNextRecKey(pTempLib, pTempRec);
            
    }while(nAdr != 0); 

	return -1;

}

int SearchRecOrder_stringkey( char * string_key, int & EmptyOrder)
{   
	if( string_key==NULL || strlen(string_key)<= 0  ) return -1; 

	int RecKey = StringkeyToRecAddr(string_key);
	if( RecKey >= 0 ) return RecKey;
	 
	int Key_id = HashGetRecKey(RTDB_STRING_KEY_NO, string_key, strlen(string_key));

	if( !IsLibNoValid(RTDB_STRING_KEY_NO) )    return -1; 
	struLibrary * pTempLib = &(SysPtr->TheLibMsgArray[RTDB_STRING_KEY_NO]);  
	if( pTempLib->IsUsed == NOTUSED ) return -1;  
	int nAdr = Key_id %  pTempLib->BaseCount;  
	 

	char* pTempRec;
	do
    {
        pTempRec = KeyToAddress(RTDB_STRING_KEY_NO, nAdr);       
        if(pTempRec == 0) return -1;
		 
		if( IsRecordUsed( pTempLib, pTempRec ) == false ) { 
			EmptyOrder = nAdr ;
			return 0;
		} 
		nAdr = hashGetNextRecKey(pTempLib, pTempRec);
            
    }while(nAdr != 0); 

	int RecKeyNext;
	RecKeyNext = pTempLib->libInfo.LibSize - 1;
            
    char* pTempRecNext;
    pTempRecNext = KeyToAddress(RTDB_STRING_KEY_NO, RecKeyNext) ;
    if(pTempRecNext == 0) return -1;
            
    while(RecKeyNext > 0)
    {
		if((*(tIfUsed*)(pTempRecNext + pTempLib->libInfo.SysFieldOffset)) == NOTUSED && 
			hashGetNextRecKey(pTempLib, pTempRec) == 0 ) 
        {
			hashSetNextRecKey(pTempLib, pTempRec, RecKeyNext);
                     
            EmptyOrder = RecKeyNext;
			return 0;
        }
                
        RecKeyNext --;
        pTempRecNext = KeyToAddress(RTDB_STRING_KEY_NO, RecKeyNext);
        if(pTempRecNext == 0) return -1;
    }

	return -1; 
} 

int InsertStringToRecDb(char * string_rec, int EmptyOrder = 0 )
{
    if( string_rec==NULL || strlen(string_rec) <= 0 ) return -1; 

	if(!IsLibNoValid(RTDB_STRING_KEY_NO))       {  
		 return -1; 
	} 

	struLibrary* pTempLib = &(SysPtr->TheLibMsgArray[RTDB_STRING_KEY_NO]);
	 
	if( strlen(string_rec) >= REC_FILED_NAME_LEN) {  
		return -1;
	}	 

	int NewEmptyOrder = 0;
	if( EmptyOrder > 0 ) 
	{
		NewEmptyOrder = EmptyOrder;
	}
	else 
	{ 
		int recOrder = SearchRecOrder_stringkey(string_rec, NewEmptyOrder);
		if( recOrder > 0 ) return -2;  //�Ѿ�����
		if( recOrder < 0 ) return -3;  //�ռ����� 
	}

	char * pRecInfo = KeyToAddress(RTDB_STRING_KEY_NO, NewEmptyOrder); 
	if( pRecInfo == NULL ) return -1;

	memcpy(pRecInfo, string_rec, strlen(string_rec)); 
	*(tIfUsed*)(pRecInfo + pTempLib->libInfo.SysFieldOffset) = ISUSED;

	pTempLib->libInfo.RecCount ++;	
 
 
	return NewEmptyOrder;
}  




/////////////////////


bool InsertRec_stringkey( int TheLibNo, char * string_key, char* RecBuf, unsigned short rec_len)
{
	if( string_key==NULL || strlen(string_key) <= 0 || rec_len<= 0 ) return false;  
	if(!IsLibNoValid(TheLibNo))       {  
		 return false; 
	}
	if( RecBuf == NULL ) {   
		return false;
	}  
	int EmptyOrder = 0;
	int recOrder = SearchRecOrder_stringkey( string_key, EmptyOrder); 
	if( recOrder < 0 ) {
		printf("�ռ����� \n");
		return false;  //�ռ�����
	}

	if( recOrder > 0 )   //ϵͳ������Ѿ����ڴ��ַ���
	{
		memcpy(RecBuf, &recOrder, sizeof(int));
		return InsertRec(TheLibNo, recOrder, RecBuf, rec_len);
	}
	else
	{
		InsertStringToRecDb(string_key, EmptyOrder);  //����ϵͳ��¼�����
		memset(RecBuf, 0, sizeof(long long));
		memcpy(RecBuf, &EmptyOrder, sizeof(int));
		return InsertRec(TheLibNo, EmptyOrder, RecBuf, rec_len);
	}  
}


bool UpdateRec_stringkey( int TheLibNo, char * string_key, char* RecBuf, unsigned short rec_len)
{
    if( string_key==NULL || strlen(string_key) <= 0 || rec_len<= 0 ) return false;  

	if(!IsLibNoValid(TheLibNo) )        return false; 

	int EmptyOrder = 0;
	int recOrder = SearchRecOrder_stringkey(string_key, EmptyOrder);
	if( recOrder < 0 )  return false;  //ϵͳ������Ѿ������ڴ��ַ��� 
	 
	if( recOrder == 0 )
	{
		recOrder= EmptyOrder;
		InsertStringToRecDb(string_key, EmptyOrder);  //����ϵͳ��¼�����
	}
	memset(RecBuf, 0, sizeof(long long));
	memcpy(RecBuf, &recOrder, sizeof(int));
	return UpdateRec(TheLibNo, recOrder, RecBuf, rec_len);
		 
}


bool UpdateRec_stringkey_Ex( int TheLibNo, char * string_key, char* RecBuf, unsigned short rec_len)
{
    if( string_key==NULL || strlen(string_key) <= 0 || rec_len<= 0 ) {
		printf("string_key=NULL or rec_len = 0 \n" );
		return false;  
	}
	if(!IsLibNoValid(TheLibNo) )   {
		printf(" IsLibNoValid(%d) =  false \n" , TheLibNo);
		return false;
	}
	if( RecBuf == NULL ) return false;
	 
	int EmptyOrder = 0;
	int recOrder = SearchRecOrder_stringkey(string_key, EmptyOrder);
	if( recOrder <  0 )  {
		printf(" SearchRecOrder_stringkey(%s) < 0 \n" , string_key);
		return false;
	}

	//TRACE("TheLibNo=%d  Key_id=%lld  EmptyOrder=%d \n", TheLibNo,  EmptyOrder);
	 
	if( recOrder == 0 )  //ϵͳ������Ѿ������ڴ��ַ���
	{
		recOrder= EmptyOrder;
		InsertStringToRecDb(string_key, EmptyOrder);  //����ϵͳ��¼�����
	}
	  
	memset(RecBuf, 0, sizeof(long long));
	memcpy(RecBuf, &recOrder, sizeof(int));
	return UpdateRec_Ex(TheLibNo, recOrder, RecBuf, rec_len);
}


//���ã�ֱ�ӷ��ع����ڴ��ַ
char * FindRec_stringkey(int TheLibNo, char * string_key)
{ 
	if( string_key==NULL || strlen(string_key) <= 0 ) return NULL;  
	int EmptyOrder = 0;
	int recOrder = StringkeyToRecAddr(string_key);
	if( recOrder <  0 ) {
		//printf("StringkeyToRecAddr < 0 : %s :not exist", string_key);
		return NULL;  //������
	}
	

	char * pTmpRec = FindRecEx(TheLibNo, recOrder);
	if( pTmpRec == NULL) {
		//printf("FindRecEx=NULL : %d :not exist \n", recOrder);
		return NULL;
	}
	 
	return pTmpRec; 
}

bool  Delete_key( int TheLibNo, char * string_key )
{
	if( string_key==NULL || strlen(string_key) <= 0 ) return false;  
	int EmptyOrder = 0;
	int recOrder = StringkeyToRecAddr(string_key);
	if( recOrder <  0 ) return false;  //������

	return Delete_key(TheLibNo, recOrder);
}
